package com.topnav.mc.listener;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.js.lib.cache.Cache;
import com.js.lib.result.Result;
import com.topnav.mc.admin.entity.Device;
import com.topnav.mc.admin.entity.DeviceChannel;
import com.topnav.mc.admin.entity.DeviceLog;
import com.topnav.mc.admin.entity.GbServer;
import com.topnav.mc.admin.entity.bean.GbServerBean;
import com.topnav.mc.admin.entity.param.GbServerParam;
import com.topnav.mc.admin.service.IDeviceChannelService;
import com.topnav.mc.admin.service.IDeviceLogService;
import com.topnav.mc.admin.service.IDeviceService;
import com.topnav.mc.admin.service.IGbServerService;
import com.topnav.mc.gbserverapi.DeviceApi;
import com.topnav.mc.gbserverapi.bean.GbDeviceChannel;
import com.topnav.mc.listener.bean.DeviceStatus;
import com.topnav.mc.listener.bean.GbDeviceChannelResult;
import com.topnav.mc.lock.SyncLock;
import com.topnav.mc.position.PositionInfo;
import com.topnav.mc.position.PositionUtil;
import com.topnav.mc.uitls.DeviceOnlineUtils;
import com.topnav.mc.uitls.MapUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 设备上下线
 * @Author: kenny
 * @Date: 2023/10/27 17:33
 */
@Component
@Slf4j
public class RedisDeviceOnlineListener implements MessageListener {
    private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
/*    private String host = "http://%s:%s";
    private String url=null;
    @Resource
    private DeviceApi deviceApi;*/
    @Autowired
    private IDeviceService deviceService;
    @Resource(name="sysCache")
    private Cache sysCache;
    @Autowired
    private PositionUtil positionUtil;
    @Autowired
    private IDeviceLogService deviceLogService;
    @Autowired
    private IGbServerService gbServerService;

    @Autowired
    private IDeviceChannelService deviceChannelService;
    @Autowired
    private DeviceOnlineUtils deviceOnlineUtils;

    @Override
    public void onMessage(Message message, byte[] bytes) {
        log.info("******* 收到设备上下线通知 {}",message.toString());
        taskQueue.offer(message);
        this.consusme();
    }

    @Async("taskExecutor")
    @SyncLock(key="RedisDeviceOnlineListener-consusGps-LOCK",dueSec = 5*60)
    public void consusme(){
        Device device = null;
        while (!taskQueue.isEmpty()) {
            Message msg = taskQueue.poll();
            DeviceStatus deviceStatus = JSON.parseObject(msg.getBody(), DeviceStatus.class);
            device = deviceService.getDeviceFromCache(deviceStatus.getDeviceId());
            if (device == null){
                continue;
            }
            if (deviceStatus.getStatus() == 1){
                log.info(">>>>> 收到设备上线通知：code:{}, 上线",deviceStatus.getDeviceId());
            }else{
                log.info(">>>>> 收到设备下线通知：code:{}, 下线",deviceStatus.getDeviceId());
            }
            //更新上下线状态并写日志
            deviceOnlineUtils.deviceStatusEvent(device,deviceStatus.getStatus(),"设备主动");

            //上线且第一次上线 同步通道列表
            if (deviceStatus.getStatus() == 1) {
                this.syncDeviceChannel(device);
                if (deviceStatus.getFirstOnline() == 1){
                    //首次上线
                    deviceService.updateDeviceToGbServer(device);
                }

            }

            try {
                Thread.sleep(5L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Async("taskExecutor")
    public void syncDeviceChannel(Device device){
        deviceService.syncDeviceChannel(device);
    }

}
